﻿/// <reference path="application.js" />
/// <reference path="scene.js" />

function CollisionPoint(x,y) {

    this.x = x;
    this.y = y;
    this.lastX = x;
    this.lastY = y;
    this.isInCollision = false;

    if(typeof CollisionPoint.initialized == "undefined") {

        /// Draw method
        CollisionPoint.prototype.Draw = function () {
            // Draw debug information
            if(app.context.isInDebugMode) {
                window.app.context.container2d.fillStyle = this.isInCollision ? "red": "black";
                window.app.context.container2d.strokeStyle = "none";
                window.app.context.container2d.lineWidth = 0;
                window.app.context.container2d.fillRect(app.UI.ToScreenX(this.x - 1), app.UI.ToScreenY(this.y + 1), 3, 3);

                // coordinates
                window.app.context.container2d.font = "9px arial";
                window.app.context.container2d.textAlign = "left";
                window.app.context.container2d.fillStyle = "#333333";
                app.context.container2d.fillText("[" + this.x + " ; " + this.y + "]", app.UI.ToScreenX(this.x + 4), app.UI.ToScreenY(this.y));
            }
        };

        /// Think method
        CollisionPoint.prototype.UpdatePosition = function (x, y) {
            // Backup last position
            this.lastX = this.x;
            this.lastY = this.y;

            // Update position with new value
            this.x = x;
            this.y = y;

            // Check collision
            if (this.isInCollision = app.data.scene.isInCollision(Math.round(x), Math.round(y))) {
                // Adjust new position to limit collision point
                this.BackInTimeToLimitCollisionPoint();
            }
        };
        
        /// Think method
        CollisionPoint.prototype.Move = function (dx, dy) {
            this.UpdatePosition(this.x + dx, this.y + dy);
        };

////////////////////////////////////////////////////////////////////
// Pseudo code pixel line algorithm: "Bresenham's line algorithm" //
////////////////////////////////////////////////////////////////////     
//        function line(x0, y0, x1, y1)
//           dx := abs(x1-x0)
//           dy := abs(y1-y0) 
//           if x0 < x1 then sx := 1 else sx := -1
//           if y0 < y1 then sy := 1 else sy := -1
//           err := dx-dy
// 
//           loop
//             setPixel(x0,y0)
//             if x0 = x1 and y0 = y1 exit loop
//             e2 := 2*err
//             if e2 > -dy then 
//               err := err - dy
//               x0 := x0 + sx
//             end if
//             if e2 <  dx then 
//               err := err + dx
//               y0 := y0 + sy 
//             end if
//           end loop
// ------------------------------------------------------------------
        /// Back in time: Browse pixel from last position to x,y until findind the limit collision point
        CollisionPoint.prototype.BackInTimeToLimitCollisionPoint = function () {
            var x0 = Math.round(this.lastX);
            var y0 = Math.round(this.lastY);
            var x1 = Math.round(this.x);
            var y1 = Math.round(this.y);
            var dx = Math.abs(x1 - x0);
            var dy = Math.abs(y1 - y0);
            var sx = x0 < x1 ? 1 : -1;
            var sy = y0 < y1 ? 1 : -1;
            var err = dx - dy;

            // loop on pixels linearly until finding a collision point
            do {
                var e2 = 2 * err;
                if (e2 > -dy) {
                    err -= dy;
                    x0 += sx;
                }
                if (e2 < dx) {
                    err += dx;
                    y0 += sy;
                }
            } while (!(app.data.scene.isInCollision(x0, y0) || (x0 == x1 && y0 == y1)));

            // the current x,y is the wanted limit collision point
            this.x = x0;
            this.y = y0;
        };

        CollisionPoint.initialized = true;
    }
}